home *** CD-ROM | disk | FTP | other *** search
/ QuickTime 2.0 Developer Kit / QuickTime 2.0 Developer Kit.iso / mac / MAC / Programming Stuff / Documentation / develop / develop Issue 15 / develop 15 code / Managing Component Registration / Loader.c < prev    next >
Encoding:
Text File  |  1993-06-02  |  7.6 KB  |  333 lines  |  [TEXT/KAHL]

  1. /*
  2.     File:        Loader.c
  3.  
  4.     Contains:    Loader component routines.
  5.     
  6.                 Refer to develop Issue 15, "Managing Component Registration",
  7.                 for details on this code.
  8.  
  9.     Written by:    Gary Woodcock
  10.  
  11.     Copyright:    © 1993 by Apple Computer, Inc.
  12.  
  13.     Change History (most recent first):
  14.  
  15. */
  16.  
  17. //-----------------------------------------------------------------------
  18. // Includes
  19.  
  20. #include "LoaderPrivate.h"
  21.  
  22. #include <Errors.h>
  23. #include <Memory.h>
  24. #include <Packages.h>
  25. #include <Resources.h>
  26. #include <SysEqu.h>
  27. #include <Events.h>
  28.  
  29. //-----------------------------------------------------------------------
  30. // Private prototypes
  31.  
  32. static OSErr
  33. LoadComponents (ResType loadListResType, short loadListResID);
  34.  
  35. //-----------------------------------------------------------------------
  36.  
  37. #ifdef BUILD_LINKED
  38.  
  39. // Use this declaration when we're running linked (for debugging)
  40. pascal ComponentResult
  41. LoaderDispatcher (ComponentParameters *params, Handle storage)
  42.                                              
  43. #else
  44.  
  45. // Use this declaration when we're a standalone component
  46. pascal ComponentResult
  47. main (ComponentParameters *params, Handle storage)
  48.  
  49. #endif BUILD_LINKED
  50.  
  51. {
  52.     // This routine is the main dispatcher for the component
  53.     
  54.     ComponentResult        result = noErr;
  55.     ComponentFunction    loaderFunction = nil;
  56.     
  57.     // Did we get a Component Manager request code (< 0)?
  58.     if (params->what < 0)
  59.     {
  60.         switch (params->what)
  61.         {
  62.             case kComponentOpenSelect:            // Open request
  63.             {
  64.                 loaderFunction = _LoaderOpen;
  65.                 break;
  66.             }
  67.             case kComponentCloseSelect:            // Close request
  68.             {
  69.                 loaderFunction = _LoaderClose;
  70.                 break;
  71.             }
  72.             case kComponentCanDoSelect:            // Can Do request
  73.             {
  74.                 result = CallComponentFunction (params, 
  75.                     (ComponentFunction) _LoaderCanDo);
  76.                 break;
  77.             }
  78.             case kComponentVersionSelect:        // Version request
  79.             {
  80.                 result = CallComponentFunction (params,
  81.                     (ComponentFunction) _LoaderVersion);
  82.                 break;
  83.             }
  84.             case kComponentRegisterSelect:        // Register request
  85.             {
  86.                 loaderFunction = _LoaderRegister;
  87.                 break;
  88.             }
  89.             case kComponentTargetSelect:        // Target request not supported
  90.             case kComponentUnregisterSelect:    // Unregister request
  91.             default:                            // Unknown request
  92.             {
  93.                 result = badComponentSelector;
  94.                 break;
  95.             }
  96.         }
  97.     }
  98.     else    // Unknown request
  99.     {
  100.         result = badComponentSelector;
  101.     }
  102.     if (loaderFunction != nil)
  103.     {
  104.         result = CallComponentFunctionWithStorage (storage, params, loaderFunction);
  105.     }
  106.     return (result);
  107. }
  108.                                              
  109. //-----------------------------------------------------------------------
  110.  
  111. pascal ComponentResult
  112. _LoaderOpen (Handle storage, ComponentInstance self)
  113. {
  114.     #pragma    unused (storage)
  115.     
  116.     ComponentResult    result = noErr;
  117.     
  118.     #ifdef THINK_C
  119.     
  120.     SetComponentInstanceA5 (self, *(long *) CurrentA5);
  121.     
  122.     #endif THINK_C
  123.     
  124.     // Can we open another instance?
  125.     if (CountComponentInstances ((Component) self) <= kMaxLoaderInstances)
  126.     {
  127.         // Get our instance storage
  128.         LoaderPrivateGlobalsHdl    globals = (LoaderPrivateGlobalsHdl) NewHandleClear (sizeof (LoaderPrivateGlobals));
  129.  
  130.         // Did we get our storage?
  131.         if (globals != nil)
  132.         {
  133.             // Keep a reference to self
  134.             (**globals).self = (Component) self;
  135.                         
  136.             // Set storage ref
  137.             SetComponentInstanceStorage (self, (Handle) globals);
  138.         }
  139.         else    // NewHandleClear failed
  140.         {
  141.             result = MemError();
  142.         }
  143.     }
  144.     else    // No more instances can be opened
  145.     {
  146.         result = -1L;    // Return anonymous error
  147.     }
  148.     return (result);
  149. }
  150.  
  151. //-----------------------------------------------------------------------
  152.  
  153. pascal ComponentResult
  154. _LoaderClose (Handle storage, ComponentInstance self)
  155. {
  156.     LoaderPrivateGlobalsHdl    globals = (LoaderPrivateGlobalsHdl) storage;
  157.     ComponentResult            result = noErr;
  158.     
  159.     // Do we have any clean up to do?
  160.     if (globals != nil)
  161.     {
  162.         // Dispose globals
  163.         DisposHandle ((Handle) globals);
  164.     }
  165.     return (result);
  166. }
  167.  
  168. //-----------------------------------------------------------------------
  169.  
  170. pascal ComponentResult
  171. _LoaderCanDo (short selector)
  172. {
  173.     // Case on the request code
  174.     switch (selector)
  175.     {
  176.         // Component Manager request codes
  177.         case kComponentOpenSelect:
  178.         case kComponentCloseSelect:
  179.         case kComponentCanDoSelect:
  180.         case kComponentVersionSelect:
  181.         case kComponentRegisterSelect:    
  182.         {
  183.             return (true);
  184.         }
  185.         
  186.         // Unsupported or unknown request codes
  187.         case kComponentTargetSelect:        // Target request not supported
  188.         case kComponentUnregisterSelect:    // Unregister request not supported
  189.         default:                            // Not a request code we recognize
  190.         {
  191.             return (false); 
  192.         }
  193.     }
  194. }
  195.  
  196. //-----------------------------------------------------------------------
  197.  
  198. pascal ComponentResult
  199. _LoaderVersion (void)
  200. {
  201.     // Return the version info
  202.     return (loaderInterfaceRev);
  203. }
  204.  
  205. //-----------------------------------------------------------------------
  206.  
  207. pascal ComponentResult
  208. _LoaderRegister (Handle storage)
  209. {
  210.     KeyMap                    keys;
  211.     LoaderPrivateGlobalsHdl    globals = (LoaderPrivateGlobalsHdl) storage;
  212.     OSErr                    result = noErr;
  213.     
  214.     #ifndef BUILD_LINKED
  215.     
  216.     short                    savedResRefNum = CurResFile();
  217.     short                    compResRefNum = OpenComponentResFile ((**globals).self);
  218.  
  219.     // Use the component's res file (not the THINK project res file) if we're
  220.     // running standalone
  221.     UseResFile (compResRefNum);
  222.     
  223.     #endif BUILD_LINKED
  224.     
  225.     // If mouse or shift key down, don't bother
  226.     GetKeys (keys);
  227.     if (!Button() && !(1 & keys[1]))
  228.     {
  229.         // Load the components!
  230.         result = LoadComponents (kComponentLoadListResType, kLoaderBaseResID);
  231.     }
  232.     
  233.     #ifndef BUILD_LINKED
  234.     
  235.     // Restore the res file (if running standalone)
  236.     CloseComponentResFile (compResRefNum);
  237.     UseResFile (savedResRefNum);
  238.     
  239.     #endif BUILD_LINKED
  240.     
  241.     return ((result == noErr) ? 0L : 1L);
  242. }
  243.  
  244. //-----------------------------------------------------------------------
  245.  
  246. static OSErr
  247. LoadComponents (ResType loadListResType, short loadListResID)
  248. {
  249.     OSErr                    result = noErr;
  250.     ComponentLoadListHdl    componentLoadList = (ComponentLoadListHdl) Get1Resource (loadListResType, loadListResID);
  251.     
  252.     // Did we get the component load list?
  253.     if (componentLoadList != nil)
  254.     {
  255.         ComponentLoadSpec        componentLoadSpec;
  256.         ComponentResourceHandle    componentResHdl;
  257.         Component                componentID;
  258.         short                    numComponentsToLoad = (**componentLoadList).count;
  259.         short                    i;
  260.         
  261.         for (i = 0; i < numComponentsToLoad; i++)
  262.         {
  263.             // Get the component load spec
  264.             componentLoadSpec = (**componentLoadList).spec[i];
  265.                 
  266.             // Get the component resource pointed to by this spec
  267.             componentResHdl = (ComponentResourceHandle) Get1Resource 
  268.                 (componentLoadSpec.componentResType, componentLoadSpec.componentResID);
  269.                 
  270.             // Did we get it?
  271.             if (componentResHdl != nil)
  272.             {
  273.                 // Register it
  274.                 componentID = RegisterComponentResource (componentResHdl, kRegisterGlobally);
  275.                 if (componentID == 0L)    // RegisterComponentResource failed
  276.                 {
  277.                     result = -1L;    // Return anonymous error
  278.                 }
  279.             }
  280.             else    // Get1Resource failed
  281.             {
  282.                 result = ResError();
  283.             }
  284.         }
  285.     }
  286.     else    // Couldn't get component loader resource
  287.     {
  288.         result = ResError();
  289.     }
  290.     return (result);
  291. }
  292.  
  293. //-----------------------------------------------------------------------
  294.  
  295. #ifdef THINK_C
  296. #ifdef BUILD_LINKED
  297.  
  298. Component
  299. RegisterLoader (void)
  300. {
  301.     ComponentDescription    theDesc;
  302.     Handle                    name;
  303.     Component                theComp;
  304.  
  305.     // Set up component description
  306.       theDesc.componentType = 'tldr';
  307.       theDesc.componentSubType = kAnyComponentSubType;
  308.     theDesc.componentManufacturer = 'appl';
  309.       theDesc.componentFlags = cmpWantsRegisterMessage;
  310.       theDesc.componentFlagsMask = kAnyComponentFlagsMask;
  311.  
  312.     // Name the component
  313.     PtrToHand ("\pLoader (linked)", &name, 15);
  314.     
  315.     // Register with the component main entry point
  316.     theComp = RegisterComponent (&theDesc, (void *)LoaderDispatcher, 0, name, 0, 0);
  317.     
  318.     // Clean up
  319.     if (name != nil)
  320.     {
  321.         DisposHandle (name);
  322.     }
  323.     return (theComp);
  324. }
  325.  
  326. #endif BUILD_LINKED
  327. #endif THINK_C
  328.  
  329. //-----------------------------------------------------------------------
  330.  
  331.  
  332.  
  333.